package com.qibao.toolkit.exception.config;

import com.qibao.toolkit.exception.BusinessExceptionHandlerStrategy;
import com.qibao.toolkit.exception.strategy.ExceptionHandleType;
import com.qibao.toolkit.exception.strategy.impl.*;
import com.qibao.toolkit.exception.strategy.properties.ExceptionProperties;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.StringUtils;

import java.util.Objects;

/**
 * @author wangcheng
 * @version $Id: ExceptionHandleStrategyConfiguration.java, v0.1 2019/5/10 9:44 wangcheng Exp $$
 */
@EnableConfigurationProperties({ExceptionProperties.class})
public  class ExceptionHandleStrategyConfiguration implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        registryExceptionProperties(registry);

        badRequestErrorHandleStrategy(registry);

        bindExceptionHandleStrategy(registry);

        constraintViolationExceptionHandleStrategy(registry);

        illegalArgumentExceptionHandleStrategy(registry);

        methodNotSupportHandlerStrategy(registry);

        businessExceptionHandlerStrategy(registry);

        defaultExceptionHandleStrategy(registry);
    }


    private void badRequestErrorHandleStrategy(BeanDefinitionRegistry registry){
        baseRegistry(registry,BadRequestErrorHandleStrategy.class);
    }

    private void bindExceptionHandleStrategy(BeanDefinitionRegistry registry){
        baseRegistry(registry,BindExceptionHandleStrategy.class);
    }

    private void constraintViolationExceptionHandleStrategy(BeanDefinitionRegistry registry){
        baseRegistry(registry,ConstraintViolationExceptionHandleStrategy.class);
    }


    private void illegalArgumentExceptionHandleStrategy(BeanDefinitionRegistry registry){
        baseRegistry(registry,IllegalArgumentExceptionHandleStrategy.class);
    }

    private void methodNotSupportHandlerStrategy(BeanDefinitionRegistry registry){
        baseRegistry(registry,MethodNotSupportHandlerStrategy.class);
    }

    private void businessExceptionHandlerStrategy(BeanDefinitionRegistry registry){
        baseRegistry(registry,BusinessExceptionHandlerStrategy.class);
    }
    private void registryExceptionProperties(BeanDefinitionRegistry registry){
        baseRegistry(registry,ExceptionProperties.class);
    }
    private void defaultExceptionHandleStrategy(BeanDefinitionRegistry registry){
        baseRegistry(registry,DefaultExceptionHandleStrategy.class);
    }
    private void baseRegistry(BeanDefinitionRegistry registry, Class clazz){
        String  name = clazz.getName();
        ExceptionHandleType annotation = (ExceptionHandleType)clazz.getAnnotation(ExceptionHandleType.class);
        if(Objects.nonNull(annotation)){
            String customName = annotation.name();
            if(StringUtils.hasText(customName)){
                name = customName;
            }
        }
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(clazz);
        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
        registry.registerBeanDefinition(name,beanDefinition);
    }
}